package com.yichi.service;

import android.util.Log;

import com.licheedev.modbus4android.ModbusRespException;
import com.serotonin.modbus4j.exception.ModbusInitException;
import com.serotonin.modbus4j.exception.ModbusTransportException;
import com.yichi.global.AppConfig;
import com.yichi.manager.ModbusRtuManager;
import com.yichi.util.JsonUtil;
import com.yichi.util.Utils;

import java.util.ArrayList;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.TimeUnit;

/**
 * ic card的服务
 * 读取电池编号
 */
public class IccardService {
    private final static String TAG = "IccardService";
    private final static Integer timeout = 10000 * 60 * 1000;//60秒
    private ModbusRtuManager modbusRtuManager;

    public static IccardService inst = new IccardService();

    private IccardService() {
    }

    public void init() {
        modbusRtuManager = new ModbusRtuManager();
        modbusRtuManager.initIccardRTU();
    }

    /**
     * 获取存电仓1的电池编号
     *
     * @return
     */
    public String queryBatteryNo1() {
        String no = queryInputStoreBatteryNo(0, timeout);
        return no;
    }

    /**
     * 获取存电仓2的电池编号
     *
     * @return
     */
    public String queryBatteryNo2() {
        String no = queryInputStoreBatteryNo(1, timeout);
        return no;
    }

    /**
     * 获取存电仓3的电池编号
     *
     * @return
     */
    public String queryBatteryNo3() {
        String no = queryInputStoreBatteryNo(2, timeout);
        return no;
    }

    /**
     * 查询存入仓1的电池编号，直到读到编号数据
     *
     * @param idx           0:第一个存电仓 1：第二个存电仓 2：第三个存电仓
     * @param timeoutMillis 超时时间，毫秒
     * @return
     */
    public String queryInputStoreBatteryNo(Integer idx, Integer timeoutMillis) {
        final CountDownLatch latch = new CountDownLatch(1); // Used to block the main thread
        final String[] result = {""}; // To store the result (it has to be an array due to lambda limitations)

        // Start a background thread to handle the async task
        Thread thread = new Thread(() -> {
            long startTime = System.currentTimeMillis();

            while (System.currentTimeMillis() - startTime < timeoutMillis) {
                try {
                    String[] strArr = queryBatteryNo();
                    //查到了电池编号
                    if (!strArr[idx].equals("")) {
                        result[0] = strArr[idx]; // Set the result to "a" when matched
                        latch.countDown(); // Signal that the result is ready
                        return; // Exit the thread
                    }

                    // Optional: Sleep for a short duration before retrying
                    Thread.sleep(1500); // Sleep for 100ms (adjust as needed)

                } catch (Exception e) {
                    Log.e(TAG, "IC Card query failed", e);
                    result[0] = ""; // Set result as empty string on error
                    latch.countDown(); // Signal completion even if failed
                    return;
                }
            }

            // 超时了
            Log.e(TAG, "Timeout reached, IC Card query failed.");
            result[0] = "";
            latch.countDown(); // Signal completion after timeout
        });

        thread.start(); // Start the background thread

        try {
            // Wait for the latch to be counted down (either by success or timeout)
            boolean completed = latch.await(timeoutMillis, TimeUnit.MILLISECONDS);

            if (!completed) {
                Log.e(TAG, "Timeout reached before receiving expected data.");
                return ""; // Timeout occurred, return empty string
            }

        } catch (InterruptedException e) {
            Thread.currentThread().interrupt();
            Log.e(TAG, "Thread was interrupted.", e);
            return ""; // Handle interruption by returning empty string
        }

        return result[0]; // Return the result (either "a" or an empty string if failed or timed out)
    }

    /**
     * 批量查询ic card的编号信息
     *
     * @return
     */
    public String[] queryBatteryNo() {
        try {
            int slaveId = AppConfig.ICCARD_SLAVE_ID;
            int offset = 1;
            int count = 42;

//        ArrayList<Integer> integers = modbusRtuManager.readMultipleRegisters(slaveId, offset, count);
//        Log.i(TAG, "收到的报文：" + JsonUtil.toJSONString(integers));
//        ArrayList<Short> shorts = Utils.integerList2ShortList(integers);
//        byte[] bytes = Utils.shortList2ByteArray(shorts);
            byte[] bytes = modbusRtuManager.readMultipleRegistersBytesSync(slaveId, offset, count);
            if (bytes == null || bytes.length <= 0) {
                return null;
            }

            byte[] boolBytes1 = Utils.subByteArray(bytes, 0, 2);
            byte[] dataBytes1 = Utils.subByteArray(bytes, 2, 26);
            int hasNo1 = Utils.twoBytesToInt(boolBytes1);
            String batteryNo1 = "";
            if (hasNo1 == 1) {
                batteryNo1 = Utils.byteArray2String(dataBytes1);
            }

            byte[] boolBytes2 = Utils.subByteArray(bytes, 28, 2);
            byte[] dataBytes2 = Utils.subByteArray(bytes, 30, 26);
            int hasNo2 = Utils.twoBytesToInt(boolBytes2);
            String batteryNo2 = "";
            if (hasNo2 == 1) {
                batteryNo2 = Utils.byteArray2String(dataBytes2);
            }

            byte[] boolBytes3 = Utils.subByteArray(bytes, 56, 2);
            byte[] dataBytes3 = Utils.subByteArray(bytes, 58, 26);
            int hasNo3 = Utils.twoBytesToInt(boolBytes3);
            String batteryNo3 = "";
            if (hasNo3 == 1) {
                batteryNo3 = Utils.byteArray2String(dataBytes3);
            }

            String[] arr = {batteryNo1, batteryNo2, batteryNo3};
            return arr;
        } catch (Exception e) {
            Log.e(TAG, e.getMessage(), e);
            return null;
        }
    }

    public void testCmd() {
        Thread thread = new Thread(() -> {
            while (true) {
                try {
                    String[] strArr = queryBatteryNo();
                    Log.i(TAG, "电池编号arr:" + JsonUtil.toJSONString(strArr));
                } catch (Exception e) {
                    Log.e(TAG, "IC Card query failed", e);
                }

                try {
                    Thread.sleep(1000); // Sleep for 100ms (adjust as needed)
                } catch (InterruptedException e) {
                    Log.e(TAG, e.getMessage(), e);
                }
            }
        });
        thread.start(); // Start the background thread
    }
}
